﻿using LunchListCore.Entities;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;

namespace LunchListAgents.Tests
{
    [TestClass]
    public class LunchAgentTest
    {
        [TestMethod]
        public void AddReservationValidTest()
        {
            DateTime createDate = new DateTime(2014, 5, 3);
            Guest guest = new Guest
            {
                GuestId = 19,
                Name = "JV",
                CreatedDateTime = createDate,
                CreatedUserId = "rr123456",
                ModifiedDateTime = createDate,
                ModifiedUserId = "rr123456",
				AdUserId = "rr123456"
            };

            Event lunchEvent = new Event
            {
				EventId = 18,
				GuestId = 19,
                EventName = "JV",
                EventDate = new DateTime(2014, 9, 2),
                CreatedDateTime = createDate,
                CreatedUserId = "rr123456",
                ModifiedDateTime = createDate,
                ModifiedUserId = "rr123456"
            };

			Reservation reservation = new Reservation
			{
				ReservationId = 2,
				GuestId = 19,
				EventId = 18,
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456"
			};

            Mock<DbSet<Guest>> mockGuest = new Mock<DbSet<Guest>>();
            mockGuest.Setup(x => x.Add(guest));

            Mock<DbSet<Event>> mockEvent = new Mock<DbSet<Event>>();
            mockEvent.Setup(x => x.Add(lunchEvent));

			Mock<DbSet<Reservation>> mockReservation = new Mock<DbSet<Reservation>>();
            mockReservation.Setup(x => x.Add(reservation));

            Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
            mockContext.Setup(x => x.Guests).Returns(mockGuest.Object);
            mockContext.Setup(x => x.Events).Returns(mockEvent.Object);
            mockContext.Setup(x => x.Reservations).Returns(mockReservation.Object);

            LunchAgent agent = new LunchAgent(mockContext.Object);
            var actualGuest = agent.AddReservation(guest, lunchEvent);

            mockReservation.Verify(m => m.Add(It.IsAny<Reservation>()), Times.Once());
            mockContext.Verify(m => m.SaveChanges(), Times.Once());
        }

		[TestMethod]
		public void RemoveReservationValidTest()
		{
			DateTime createDate = new DateTime(2014, 5, 3);
			Guest guest = new Guest
			{
				GuestId = 19,
				Name = "JV",
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456",
				AdUserId = "rr123456"
			};

			Event lunchEvent = new Event
			{
				EventId = 18,
				GuestId = 19,
				EventName = "JV",
				EventDate = new DateTime(2014, 9, 2),
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456"
			};
			Reservation reservation = new Reservation
			{
				ReservationId = 2,
				GuestId = 19,
				EventId = 18,
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456"
			};

			IQueryable<Guest> guests = new List<Guest> 
            { 
                 guest
            }.AsQueryable();

			Mock<DbSet<Guest>> mockGuest = new Mock<DbSet<Guest>>();
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.Provider).Returns(guests.Provider);
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.Expression).Returns(guests.Expression);
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.ElementType).Returns(guests.ElementType);
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.GetEnumerator()).Returns(guests.GetEnumerator());
			
			IQueryable<Event> events = new List<Event> 
            { 
                lunchEvent
            }.AsQueryable();

			Mock<DbSet<Event>> mockEvent = new Mock<DbSet<Event>>();
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(events.Provider);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(events.Expression);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(events.ElementType);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(events.GetEnumerator());


			IQueryable<Reservation> data = new List<Reservation> 
            { 
                new Reservation { ReservationId = 1, GuestId = 19, EventId = 19, CreatedDateTime = createDate, CreatedUserId = "rr123456", ModifiedDateTime = createDate, ModifiedUserId = "rr123456"}, 
                new Reservation { ReservationId = 2, GuestId = 19, EventId = 18, CreatedDateTime = createDate, CreatedUserId = "rr123456", ModifiedDateTime = createDate, ModifiedUserId = "rr123456"}, 
                new Reservation { ReservationId = 4, GuestId = 9, EventId = 1, CreatedDateTime = createDate, CreatedUserId = "rr123456", ModifiedDateTime = createDate, ModifiedUserId = "rr123456"}, 
            }.AsQueryable();

			Mock<DbSet<Reservation>> mockSet = new Mock<DbSet<Reservation>>();
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.Provider).Returns(data.Provider);
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.Expression).Returns(data.Expression);
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.ElementType).Returns(data.ElementType);
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
			mockSet.Setup(m => m.Remove(reservation));

			Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
			mockContext.Setup(x => x.Guests).Returns(mockGuest.Object);
			mockContext.Setup(x => x.Events).Returns(mockEvent.Object);
			mockContext.Setup(x => x.Reservations).Returns(mockSet.Object);

			LunchAgent agent = new LunchAgent(mockContext.Object);
			var res = agent.RemoveReservation(guest, lunchEvent);

			mockSet.Verify(m => m.Remove(It.IsAny<Reservation>()), Times.Once());
			mockContext.Verify(m => m.SaveChanges(), Times.Once());
		}

		[TestMethod]
		[ExpectedException(typeof(Exception))]
		public void RemoveReservationInvalidTest()
		{
			DateTime createDate = new DateTime(2014, 5, 3);
			Guest guest = new Guest
			{
				GuestId = 19,
				Name = "JV",
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456",
				AdUserId = "rr123456"
			};

			Event lunchEvent = new Event
			{
				EventId = 18,
				GuestId = 19,
				EventName = "JV",
				EventDate = new DateTime(2014, 9, 2),
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456"
			};
			Reservation reservation = new Reservation
			{
				ReservationId = 2,
				GuestId = 19,
				EventId = 18,
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456"
			};

			IQueryable<Guest> guests = new List<Guest> 
            { 
                 guest
            }.AsQueryable();

			Mock<DbSet<Guest>> mockGuest = new Mock<DbSet<Guest>>();
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.Provider).Returns(guests.Provider);
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.Expression).Returns(guests.Expression);
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.ElementType).Returns(guests.ElementType);
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.GetEnumerator()).Returns(guests.GetEnumerator());

			IQueryable<Event> events = new List<Event> 
            { 
                lunchEvent
            }.AsQueryable();

			Mock<DbSet<Event>> mockEvent = new Mock<DbSet<Event>>();
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(events.Provider);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(events.Expression);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(events.ElementType);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(events.GetEnumerator());


			IQueryable<Reservation> data = new List<Reservation> 
            { 
                new Reservation { ReservationId = 1, GuestId = 19, EventId = 19, CreatedDateTime = createDate, CreatedUserId = "rr123456", ModifiedDateTime = createDate, ModifiedUserId = "rr123456"}, 
                new Reservation { ReservationId = 4, GuestId = 9, EventId = 1, CreatedDateTime = createDate, CreatedUserId = "rr123456", ModifiedDateTime = createDate, ModifiedUserId = "rr123456"}, 
            }.AsQueryable();

			Mock<DbSet<Reservation>> mockSet = new Mock<DbSet<Reservation>>();
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.Provider).Returns(data.Provider);
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.Expression).Returns(data.Expression);
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.ElementType).Returns(data.ElementType);
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
			mockSet.Setup(m => m.Remove(reservation));

			string expectedException = "Unable to remove the guest from the event, they are not registered for it.";
			try
			{
				Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
				mockContext.Setup(x => x.Guests).Returns(mockGuest.Object);
				mockContext.Setup(x => x.Events).Returns(mockEvent.Object);
				mockContext.Setup(x => x.Reservations).Returns(mockSet.Object);

				LunchAgent agent = new LunchAgent(mockContext.Object);
				var res = agent.RemoveReservation(guest, lunchEvent);
			}
			catch (Exception ex)
			{
				Assert.AreEqual(expectedException, ex.Message);
				throw ex;
			}
		}

		[TestMethod]
		public void GetGuestsValidTest()
		{
			DateTime createDate = new DateTime(2014, 5, 3);
			
			Event lunchEvent = new Event
			{
				EventId = 18,
				GuestId = 19,
				EventName = "JV",
				EventDate = new DateTime(2014, 9, 2),
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456"
			};

			IQueryable<Guest> guests = new List<Guest> 
            { 
				new Guest { GuestId = 9, Name = "MB", CreatedDateTime = createDate, CreatedUserId = "rr123455", ModifiedDateTime = createDate, ModifiedUserId = "rr123455", AdUserId = "rr123455" },
                new Guest { GuestId = 19, Name = "JV", CreatedDateTime = createDate, CreatedUserId = "rr123456", ModifiedDateTime = createDate, ModifiedUserId = "rr123456", AdUserId = "rr123456" }
            }.AsQueryable();

			Mock<DbSet<Guest>> mockGuest = new Mock<DbSet<Guest>>();
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.Provider).Returns(guests.Provider);
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.Expression).Returns(guests.Expression);
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.ElementType).Returns(guests.ElementType);
			mockGuest.As<IQueryable<Guest>>().Setup(m => m.GetEnumerator()).Returns(guests.GetEnumerator());

			IQueryable<Event> events = new List<Event> 
            { 
				lunchEvent
                //new Event { EventId = 18, GuestId = 19, EventName = "JV", EventDate = new DateTime(2014, 9, 2), CreatedDateTime = createDate, CreatedUserId = "rr123456", ModifiedDateTime = createDate, ModifiedUserId = "rr123456"}
            }.AsQueryable();

			Mock<DbSet<Event>> mockEvent = new Mock<DbSet<Event>>();
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(events.Provider);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(events.Expression);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(events.ElementType);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(events.GetEnumerator());


			IQueryable<Reservation> data = new List<Reservation> 
            { 
                new Reservation { ReservationId = 1, GuestId = 19, EventId = 18, CreatedDateTime = createDate, CreatedUserId = "rr123456", ModifiedDateTime = createDate, ModifiedUserId = "rr123456"}, 
                new Reservation { ReservationId = 4, GuestId = 9, EventId = 18, CreatedDateTime = createDate, CreatedUserId = "rr123456", ModifiedDateTime = createDate, ModifiedUserId = "rr123456"}, 
            }.AsQueryable();

			Mock<DbSet<Reservation>> mockSet = new Mock<DbSet<Reservation>>();
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.Provider).Returns(data.Provider);
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.Expression).Returns(data.Expression);
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.ElementType).Returns(data.ElementType);
			mockSet.As<IQueryable<Reservation>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

			Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
			mockContext.Setup(x => x.Guests).Returns(mockGuest.Object);
			mockContext.Setup(x => x.Events).Returns(mockEvent.Object);
			mockContext.Setup(x => x.Reservations).Returns(mockSet.Object);

			var agent = new LunchAgent(mockContext.Object);
			var guestsReturned = agent.GetGuests(lunchEvent);

			Assert.AreEqual(2, guestsReturned.Count);
			Assert.AreEqual("MB", guestsReturned[0].Name);
			Assert.AreEqual("JV", guestsReturned[1].Name);
		}

		[TestMethod]
		public void AddEventValidTest()
		{
			DateTime createDate = new DateTime(2014, 5, 3);
			string eventName = "Subway";
			string adLogin = "rr123456";

			Guest guest = new Guest
			{
				GuestId = 19,
				Name = "JV",
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456",
				AdUserId = "rr123456"
			};

			IQueryable<Event> events = new List<Event> 
            { 

			}.AsQueryable();

			Mock<DbSet<Event>> mockEvent = new Mock<DbSet<Event>>();
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(events.Provider);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(events.Expression);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(events.ElementType);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(events.GetEnumerator());

			Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
			mockContext.Setup(x => x.Events).Returns(mockEvent.Object);

			var agent = new LunchAgent(mockContext.Object);
			var eventReturned = agent.AddEvent(eventName, createDate, guest, adLogin);

			mockEvent.Verify(m => m.Add(It.IsAny<Event>()), Times.Once());
			mockContext.Verify(m => m.SaveChanges(), Times.Once());
		}

		/// <summary>
		/// Date is invalid
		/// </summary>
		[TestMethod]
		[ExpectedException(typeof(Exception))]
		public void AddEventInvalidTest()
		{
			DateTime createDate = new DateTime(2011, 5, 3);
			string eventName = "Subway";
			string adLogin = "rr123456";

			Guest guest = new Guest
			{
				GuestId = 19,
				Name = "JV",
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456",
				AdUserId = "rr123456"
			};

			IQueryable<Event> events = new List<Event>
			{

			}.AsQueryable();

			Mock<DbSet<Event>> mockEvent = new Mock<DbSet<Event>>();
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(events.Provider);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(events.Expression);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(events.ElementType);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(events.GetEnumerator());

			Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
			mockContext.Setup(x => x.Events).Returns(mockEvent.Object);

			var agent = new LunchAgent(mockContext.Object);
			var eventReturned = agent.AddEvent(eventName, createDate, guest, adLogin);

			mockEvent.Verify(m => m.Add(It.IsAny<Event>()), Times.Once());
			mockContext.Verify(m => m.SaveChanges(), Times.Once());
		}

		[TestMethod]
		public void GetEventsValidTest()
		{
			DateTime createDate = new DateTime(2014, 5, 3);
			DateTime eventDate = new DateTime(2014, 9, 2);

			Event lunchEvent = new Event
			{
				EventId = 18,
				GuestId = 19,
				EventName = "JV",
				EventDate = eventDate,
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456"
			};

			Event lunchEvent2 = new Event
			{
				EventId = 19,
				GuestId = 19,
				EventName = "JV2",
				EventDate = eventDate,
				CreatedDateTime = createDate,
				CreatedUserId = "rr123456",
				ModifiedDateTime = createDate,
				ModifiedUserId = "rr123456"
			};

			IQueryable<Event> events = new List<Event>
			{
				lunchEvent,
				lunchEvent2
			}.AsQueryable();

			Mock<DbSet<Event>> mockEvent = new Mock<DbSet<Event>>();
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(events.Provider);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(events.Expression);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(events.ElementType);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(events.GetEnumerator());

			Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
			mockContext.Setup(x => x.Events).Returns(mockEvent.Object);

			var agent = new LunchAgent(mockContext.Object);
			var eventReturned = agent.GetEvents(eventDate);

			Assert.AreEqual(2, eventReturned.Count);
			Assert.AreEqual("JV", eventReturned[0].EventName);
			Assert.AreEqual("JV2", eventReturned[1].EventName);
		}

		[TestMethod]
		public void GetEventsInvalidTest()
		{
			DateTime createDate = new DateTime(2014, 5, 3);
			DateTime eventDate = new DateTime(2014, 9, 2);

			IQueryable<Event> events = new List<Event>
			{
			}.AsQueryable();

			Mock<DbSet<Event>> mockEvent = new Mock<DbSet<Event>>();
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(events.Provider);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(events.Expression);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(events.ElementType);
			mockEvent.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(events.GetEnumerator());

			
			Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
			mockContext.Setup(x => x.Events).Returns(mockEvent.Object);

			var agent = new LunchAgent(mockContext.Object);
			var eventReturned = agent.GetEvents(eventDate);

			Assert.IsNull(eventReturned);

		}

        //[TestMethod]
        //[ExpectedException(typeof(Exception))]
        //public void GetGuestsInvalidTest()
        //{
        //    DateTime date = DateTime.Now;
        //    var data = new List<Guest> 
        //    { 
        //        new Guest { Name = "JV" }, 
        //        new Guest { Name = "LG" }, 
        //        new Guest { Name = "GS" }, 
        //    }.AsQueryable();

        //    var mockSet = new Mock<DbSet<Guest>>();
        //    mockSet.As<IQueryable<Guest>>().Setup(m => m.Provider).Returns(data.Provider);
        //    mockSet.As<IQueryable<Guest>>().Setup(m => m.Expression).Returns(data.Expression);
        //    mockSet.As<IQueryable<Guest>>().Setup(m => m.ElementType).Returns(data.ElementType);
        //    mockSet.As<IQueryable<Guest>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

        //    DateTime errorDate = DateTime.Now;
        //    errorDate = errorDate.AddDays(-300);
        //    string expectedException = "There are no guests registered for lunch on " + errorDate.ToShortDateString();

        //    try
        //    {
        //        var mockContext = new Mock<LunchListEntities>();
        //        mockContext.Setup(x => x.Guests).Returns(mockSet.Object);

        //        var agent = new LunchAgent(mockContext.Object);
        //        agent.GetGuests(errorDate.ToShortDateString());
        //    }
        //    catch (Exception ex)
        //    {
        //        Assert.AreEqual(expectedException, ex.Message);
        //        throw ex;
        //    }
        //}

        [TestMethod]
        public void GetUpcomingEventsTest()
        {
            DateTime date = DateTime.Now;
            IQueryable<Event> data = new List<Event> 
                { 
                    new Event { EventName = "PastEvent", EventDate = new DateTime(2011,12,5,12,0,0)}, 
                    new Event { EventName = "EventA1",   EventDate = new DateTime(2064,12,5,12,0,0)},  
                    new Event { EventName = "EventA2",   EventDate = new DateTime(2064,12,5,13,0,0)}, 
                    new Event { EventName = "EventB",    EventDate = new DateTime(2064,12,7,12,0,0)} 
                }.AsQueryable();

            Mock <DbSet<Event>> mockSet = new Mock<DbSet<Event>>();
            mockSet.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(data.Provider);
            mockSet.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(data.Expression);
            mockSet.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(data.ElementType);
            mockSet.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

            Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
            mockContext.Setup(x => x.Events).Returns(mockSet.Object);

            LunchAgent agent = new LunchAgent(mockContext.Object);
            IList<DateTime> result = agent.GetUpcomingEventDates();

            Assert.AreEqual(2, result.Count, "Expected 2 eventdates");
 
        }

        [TestMethod]
        public void GetEventsTest()
        {
            DateTime? eventDate = null;
            IQueryable<Event> data = new List<Event> 
                { 
                    new Event { EventName = "PastEvent", EventDate = new DateTime(2011,12,5,12,0,0)}, 
                    new Event { EventName = "EventA1",   EventDate = new DateTime(2064,12,5,12,0,0)},  
                    new Event { EventName = "EventA2",   EventDate = new DateTime(2064,12,5,13,0,0)}, 
                    new Event { EventName = "EventB",    EventDate = new DateTime(2014,10,3,12,0,0)} 
                }.AsQueryable();

            Mock<DbSet<Event>> mockEventSet = new Mock<DbSet<Event>>();
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(data.Provider);
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(data.Expression);
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(data.ElementType);
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());


            var mockContext = new Mock<LunchListEntities>();
            mockContext.Setup(x => x.Events).Returns(mockEventSet.Object);
                        
            LunchAgent agent = new LunchAgent(mockContext.Object);
            var returnedEvents = agent.GetEvents(eventDate);

            Assert.AreEqual(mockEventSet.Object.Count(), returnedEvents.Count());
        }

		[TestMethod]
		public void GetEvents_CheckEventName_Test()
		{
			DateTime? eventDate = null;
			IQueryable<Event> data = new List<Event> 
                { 
                    new Event { EventName = "PastEvent", EventDate = new DateTime(2011,12,5,12,0,0)}, 
                    new Event { EventName = "EventA1",   EventDate = new DateTime(2064,12,5,12,0,0)},  
                    new Event { EventName = "EventA2",   EventDate = new DateTime(2064,12,5,13,0,0)}, 
                    new Event { EventName = "EventB",    EventDate = new DateTime(2014,10,3,12,0,0)} 
                }.AsQueryable();

			Mock<DbSet<Event>> mockEventSet = new Mock<DbSet<Event>>();
			mockEventSet.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(data.Provider);
			mockEventSet.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(data.Expression);
			mockEventSet.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(data.ElementType);
			mockEventSet.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());


			var mockContext = new Mock<LunchListEntities>();
			mockContext.Setup(x => x.Events).Returns(mockEventSet.Object);

			LunchAgent agent = new LunchAgent(mockContext.Object);
			var returnedEvents = agent.GetEvents(eventDate);

			Assert.AreEqual(mockEventSet.Object.Count(), returnedEvents.Count());
			Assert.AreEqual("PastEvent", returnedEvents[0].EventName);
			Assert.AreEqual("EventA1", returnedEvents[1].EventName);
			Assert.AreEqual("EventA2", returnedEvents[2].EventName);
			Assert.AreEqual("EventB", returnedEvents[3].EventName);
		}

        [TestMethod]
        public void GetEvents_ReturnsEventsForSpecificDate_Test()
        {
            DateTime? eventDate = new DateTime(2014, 10, 3);
            IQueryable<Event> data = new List<Event> 
                { 
                    new Event { EventName = "PastEvent", EventDate = new DateTime(2011,12,5,12,0,0)}, 
                    new Event { EventName = "EventA1",   EventDate = new DateTime(2064,12,5,12,0,0)},  
                    new Event { EventName = "EventA2",   EventDate = new DateTime(2064,12,5,13,0,0)}, 
                    new Event { EventName = "EventB",    EventDate = new DateTime(2014,10,3,12,0,0)} 
                }.AsQueryable();

            Mock<DbSet<Event>> mockEventSet = new Mock<DbSet<Event>>();
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(data.Provider);
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(data.Expression);
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(data.ElementType);
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

            
            var mockContext = new Mock<LunchListEntities>();
            mockContext.Setup(x => x.Events).Returns(mockEventSet.Object);

            LunchAgent agent = new LunchAgent(mockContext.Object);
            var returnedEvents = agent.GetEvents(eventDate);

            Assert.AreEqual(1, returnedEvents.Count());
        }

        [TestMethod]
        public void GetEvents_ReturnsNullForEvents_Test()
        {
            DateTime? eventDate = new DateTime(2025, 7, 17);
            IQueryable<Event> data = new List<Event> 
                { 
                    new Event { EventName = "PastEvent", EventDate = new DateTime(2011,12,5,12,0,0)}, 
                    new Event { EventName = "EventA1",   EventDate = new DateTime(2064,12,5,12,0,0)},  
                    new Event { EventName = "EventA2",   EventDate = new DateTime(2064,12,5,13,0,0)}, 
                    new Event { EventName = "EventB",    EventDate = new DateTime(2014,10,3,12,0,0)} 
                }.AsQueryable();

            Mock<DbSet<Event>> mockEventSet = new Mock<DbSet<Event>>();
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.Provider).Returns(data.Provider);
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.Expression).Returns(data.Expression);
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.ElementType).Returns(data.ElementType);
            mockEventSet.As<IQueryable<Event>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());


            var mockContext = new Mock<LunchListEntities>();
            mockContext.Setup(x => x.Events).Returns(mockEventSet.Object);

            LunchAgent agent = new LunchAgent(mockContext.Object);
            var returnedEvents = agent.GetEvents(eventDate);

            Assert.IsNull(returnedEvents);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void GetEvents_ThrowsException_WhenNoEvents_Test()
        {
            DateTime? eventDate = new DateTime(2025, 7, 17);

            var mockContext = new Mock<LunchListEntities>();
            mockContext.Setup(x => x.Events).Returns((DbSet<Event>)null);

            LunchAgent agent = new LunchAgent(mockContext.Object);
            var returnedEvents = agent.GetEvents(eventDate);

        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void AddEventInvalidDateTest()
        {
            try
            {
                DateTime createDate = new DateTime(2014, 2, 29);
                string eventName = "Buffalo Wild Wings";
                string adLogin = "rr123456";

                Guest guest = new Guest
                {
                    GuestId = 1,
                };

                Event newEvent = new Event
                {
                    GuestId = 1,
                    EventDate = createDate,
                    EventName = eventName,
                    CreatedDateTime = createDate,
                    CreatedUserId = adLogin,
                    ModifiedDateTime = createDate,
                    ModifiedUserId = adLogin,
                };

                Mock<DbSet<Event>> mockEvent = new Mock<DbSet<Event>>();
                mockEvent.Setup(x => x.Add(newEvent));

                Mock<LunchListEntities> mockContext = new Mock<LunchListEntities>();
                mockContext.Setup(x => x.Events).Returns(mockEvent.Object);

                var agent = new LunchAgent(mockContext.Object);
                var eventReturned = agent.AddEvent(eventName, createDate, guest, adLogin);
            }
            catch (Exception ex)
            {
                Assert.AreEqual("Year, Month, and Day parameters describe an un-representable DateTime.", ex.Message);
                throw ex;
            }            
        }
    }
}